#include <iostream>
#include <vector>
#include <queue>
#include <unistd.h>
#include <pthread.h>

using namespace std;

template<typename T>
class ThreadPool{

private:
    static void* thread_routine(void* args){
        ThreadPool* pool = (ThreadPool*)args;
        pthread_mutex_t& mutex =  pool->mutex_;
        pthread_cond_t& cond = pool->cond_;
        queue<T>& task = pool->tasks_;
        while (1){
            pthread_mutex_lock(&mutex);
            while(task.empty()){
                pthread_cond_wait( &cond, &mutex);
            }
            T t = task.front();            
            task.pop();
            pthread_mutex_unlock(&mutex);
            cout << "线程：" << gettid() << "，处理了任务：" << t << endl;

        }
    }
    // 为什么要加 static？
    // 因为pthread_create(&threads_[i], NULL, thread_routine, this) 的传参没考虑到 成员函数隐含的 this指针
    // static 修饰的函数 无 this指针

public:
    void start(){
        int num = max_size_;
        for (int i = 0; i < num; i++){
            pthread_create(&threads_[i], NULL, thread_routine, this);  // 传this指针，因为静态函数无法访问类成员变量
        }
    }

    void pushTask(const T& task){
        pthread_mutex_lock(&mutex_);
        tasks_.push(task);
        pthread_cond_signal(&cond_);   // 唤醒一个线程
        pthread_mutex_unlock(&mutex_);
    }

    pthread_mutex_t& getMutex(){
        return mutex_;
    }
    pthread_cond_t& getCond(){
        return cond_;
    }
    queue<T>& getTasks(){
        return tasks_;
    }
    static ThreadPool<T>* getInstance (){  // 获取单例  静态函数虽然无法直接访问 成员变量，但可以访问静态成员变量
        if (tp_ == nullptr){
            pthread_mutex_lock(&mutex_static);
            if (tp_ == nullptr){
                cout << "获取单例" << endl;
                tp_ = new ThreadPool<T>();
            }
            pthread_mutex_unlock (&mutex_static);
        }
        return tp_;
    }
private:
    ThreadPool(int max_size = 5) 
    : max_size_(max_size) 
    , threads_(max_size)
    {
        pthread_mutex_init(&mutex_, NULL);
        pthread_cond_init(&cond_, NULL);
    }

    // 确保 线程池单例，防止创建多个线程池对象
    ThreadPool(const ThreadPool&) = delete;  
    ThreadPool& operator=(const ThreadPool&) = delete;

    ~ThreadPool(){
        for(auto& t : threads_) {
            pthread_cancel(t);  // 请求线程终止
            pthread_join(t, nullptr);  // 等待线程结束
        }
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&cond_);
    }
private:
    int max_size_;   // 开辟的线程数，也即 可接纳的任务数
    vector< pthread_t> threads_;
    queue<T> tasks_;

    pthread_mutex_t mutex_;
    pthread_cond_t cond_;

    static ThreadPool<T> * tp_;
    static pthread_mutex_t mutex_static;
};

template<typename T>
ThreadPool<T>* ThreadPool<T>::tp_ = nullptr;  // 静态成员变量初始化

template<typename T>
pthread_mutex_t ThreadPool<T>::mutex_static = PTHREAD_MUTEX_INITIALIZER;  // 定义全局静态锁